package com.ltu.controller;

import java.util.Date;
import java.util.Objects;

import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.ltu.base.State;
import com.ltu.config.shiro.ShiroUserService;
import com.ltu.config.shiro.ShiroUtil;
import com.ltu.config.shiro.dto.LoginReq;
import com.ltu.config.shiro.dto.UserDto;
import com.ltu.constant.AccountType;
import com.ltu.constant.CommonConstant;
import com.ltu.convert.UserItemConvert;
import com.ltu.domain.mp_entity.UserEntity;
import com.ltu.domain.mp_entity.customize.CompanyEntity;
import com.ltu.model.request.user.UserForgotPassword;
import com.ltu.model.request.user.UserRegisterReq;
import com.ltu.model.request.user.UserResetPasswordReq;
import com.ltu.model.request.user.WxMaLoginReq;
import com.ltu.model.response.CodeResp;
import com.ltu.model.response.base.CodeDataResp;
import com.ltu.model.response.dto.AccountLoginDto;
import com.ltu.model.response.dto.UserInfoItem;
import com.ltu.service.UserService;
import com.ltu.service.customize.CompanyService;
import com.ltu.util.BeanMapper;
import com.ltu.util.common.StrUtils;
import com.ltu.util.exception.ApiException;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;

@Slf4j
@RestController
@RequestMapping("/login")
@Api(tags = "A-登录注册重置")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class LoginController {
	private final UserService userService;
	private final ShiroUserService shiroUserService;
	private final CompanyService companyService;
	 private final WxMpService wxService;
	 private final UserItemConvert userItemConvert;
	 
	@ApiOperation(value = "G:登录", notes = "内部登录")
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public CodeDataResp<UserInfoItem> login(@Valid @RequestBody LoginReq userLoginReq) {
		return BeanMapper.copyRespDataItem(userService.login(userLoginReq), UserInfoItem.class.getName());
	}

    @ApiOperation(value="G:后台管理登录", notes = "后台管理员登录")
    @RequestMapping(value="/accountLogin", method= RequestMethod.POST)
	public CodeDataResp<AccountLoginDto> accountLogin(@Valid @RequestBody LoginReq userLoginReq) {
		userLoginReq.setType(2);
		return BeanMapper.copyRespDataItem(userService.loginByAccount(userLoginReq), AccountLoginDto.class.getName());
	}

//    @ApiOperation(value="G:短信验证码登录", notes = "")
//    @RequestMapping(value="/loginBySmsCode", method= RequestMethod.POST)
//    public CodeDataResp<UserInfoItem> loginBySmsCode( @RequestBody SmsCodeLoginReq userLoginReq) {
//        return BeanMapper.copyRespDataItem(userService.loginBySmsCode(userLoginReq), UserInfoItem.class.getName());
//    }

	@ApiOperation(value = "G:小程序登录", notes = "小程序用户一键授权登录，未注册用户自动注册后登陆")
	@RequestMapping(value = "/loginByMawx", method = RequestMethod.POST)
	public CodeDataResp<UserInfoItem> loginByMawx(@Valid @RequestBody WxMaLoginReq userLoginReq)  {
		 CodeDataResp<UserEntity> resp=null;
		try {
			resp = userService.loginByWx(userLoginReq);
		} catch (WxErrorException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return BeanMapper.copyRespDataItem(resp,UserInfoItem.class.getName());
	}

//    @ApiOperation(value="G:修改绑定的手机号", notes = "")
//    @RequestMapping(value="/editAccount", method= RequestMethod.POST)
//    public CodeDataResp<UserInfoItem> editAccount(@Valid @RequestBody SmsCodeLoginReq userLoginReq) {
//    	
//    	Integer userId=Integer.parseInt( ShiroUtil.getPrincipalUserId());
//    	//修改账号
//    	userService.editUserPhone(userId,userLoginReq.getUsername());
//    	//注销原来的用户
//    	shiroUserService.userLogout();
//      	//将用户信息和验证码重新登录
//        return BeanMapper.copyRespDataItem(userService.loginBySmsCode(userLoginReq), UserInfoItem.class.getName());
//    }


//	@RequiresRoles(value={AccountType.ACCOUNT_TYPE_SYS_STAFF})
	@ApiOperation(value = "G:冻结用户")
	@RequestMapping(value = "/freeze", method = RequestMethod.GET)
	public CodeDataResp freeze(@RequestParam ("userId") String userId,@RequestParam ("status") Byte status) {
			UserDto  account = ShiroUtil.getPrincipalUser();
			//必须是代理商，修改用户状态，将用户踢下线，
			UserEntity  user =  this.userService.getById(userId);
			
			user.setStatus(status);
			this.userService.updateById(user);

				UserDto userDto =	this.shiroUserService.getUserDto(user);
				shiroUserService.removeShiroUser(userDto.getJwtUserKey());
				userDto.setUsername("");
				userDto.setJwtUserKey();
				shiroUserService.removeShiroUser(userDto.getJwtUserKey());
		return  CodeDataResp.valueOfSuccessEmptyData();
	}
	
	@ApiOperation(value = "G:用户注销接口")
	@RequestMapping(value = "/logout", method = RequestMethod.GET)
	public CodeResp logout() {
		return userService.logout();
	}


//    @ApiOperation(value="G:重置密码", notes = "密码字段需进行大写MD5两次后再进行传递")
//    @RequestMapping(value="/resetPassword", method= RequestMethod.POST)
	public CodeDataResp resetPassword(@Valid @RequestBody UserResetPasswordReq req) {
		req.setUserId(ShiroUtil.getPrincipalUserId());
		return userService.resetPassword(req);
	}

//
//    @ApiOperation(value="G:忘记密码-短信重置", notes = "找回密码后会自动登录，并返回登录后的用户信息。密码字段需进行大写MD5两次后再进行传递")
//    @RequestMapping(value="/forgotPassword", method= RequestMethod.POST)
	public CodeDataResp forgotPassword(@Valid @RequestBody UserForgotPassword req) {
		return userService.forgotPassword(req);
	}

		@ApiOperation(value = "H5端登录",notes = "	1、进入网站指定页，指定页生成跳转到微信授权页的地址，获取code\r\n"
				+ "	    	2、用户进入授权页后同意授权，则会重定向到网站登录页\r\n"
				+ "	    	3、进入网站登录页把code和companyId传给API服务端，服务端根据code  appID secrete获取：accessToken、refresh_token、 unionid、openid\r\n"
				+ "	    	4、服务端 取到accessToken后进行缓存，再通过accessToken 调用https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID 获取用户个人信息	保存本次授权记录\r\n"
				+ "	    	5、返回登录的token 和用户的unionid给前端，前端缓存 unionid和token， token会过期，但unionid永不过期\r\n"
				+ "	    	6、前端获取code前检查是否存在unionid，若存在则直接走登录接口，不存在则 走 第1步" )
	    @RequestMapping(value="/gzh/auth/{companyId}", method= RequestMethod.GET)
	    public CodeDataResp<UserInfoItem> greetUser(@PathVariable Integer companyId, @RequestParam(required = false) String wxcode, @RequestParam(required = false) String unionid, @RequestParam(required = false) String parentId) {
	    	CompanyEntity  company = this.companyService.getMeById(companyId);
	    	UserEntity sysUser = null;
	    	if(StringUtils.isNotBlank(unionid)) {
	    		 sysUser = this.userService.getUserByUnionid(unionid,1, company.getCompanyCode());
	    	}else{
	    		if(StringUtils.isBlank(wxcode))
	    			return  CodeDataResp.valueOfFailed("unionid或code必传一项");
	    		 if (!this.wxService.switchover(company.getAppId())) {
	 	            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", company.getCompanyName()));
	 	        }
	 	        try {
	 	            WxOAuth2AccessToken accessToken = wxService.getOAuth2Service().getAccessToken(wxcode);
	 	       sysUser = this.userService.refreshUserByUnionid(accessToken.getUnionId(),1, company.getCompanyCode());
	 	       	if(sysUser==null) {
	 	       	sysUser =  new UserEntity();
					if(accessToken!=null) {
						sysUser.setOpenId(accessToken.getOpenId());
					}
					sysUser.setUserType(1);
					sysUser.setPassword("10242015.");
					sysUser.setLoginCount(0);
					sysUser.setStatus((byte) 1);
					sysUser.setRoleType((byte) 1);
					sysUser.setCreateTime(new Date());
					String code = StrUtils.getCode("0","U", new Date());
					sysUser.setCode(code);
					JSONObject param = new JSONObject();
					param.put("code", code);
//					String  returnPath=QRCodeUtil.getQrCodePath(QRCodeTypeEnum.UserQrcode,param);
//					sysUser.setQrCodePath(returnPath);
		            WxOAuth2UserInfo wxuser = wxService.getOAuth2Service().getUserInfo(accessToken, null);
					sysUser.setNickName(wxuser.getNickname());
					sysUser.setHeadPhoto(wxuser.getHeadImgUrl());
					if(wxuser !=null  && StringUtils.isNotBlank(wxuser.getNickname())  && !StringUtils.equals("微信用户", wxuser.getNickname())) 
						   this.userService.save(sysUser);	
					else
						return  CodeDataResp.valueOfSuccess(null);
				 
					this.userService.updateById(sysUser);
	 	       	}
	 	        } catch (WxErrorException e) {
	 	            log.error(e.getMessage());
	 	            e.printStackTrace();
	 	        } catch (Exception e) {
	 	        	e.printStackTrace();
	 	            log.error(e.getMessage());
	 	        }	    		
	    	}
	    	LoginReq loginReq = new LoginReq();
			loginReq.setPassword(sysUser.getPassword());
			loginReq.setType(1);//移动端登录
			loginReq.setRoleType(1);//客户登录
			CodeDataResp<UserEntity> resp =	userService.login(sysUser,loginReq);
			UserInfoItem item =	 userItemConvert.sourceToReturn(sysUser);
			item.setLoginToken(resp.getData().getLoginToken());
			return  CodeDataResp.valueOfSuccess(item) ;

	    }
	
	
}
